using namespace System.Management.Automation.Host
param
(
    [boolean]$nonCommercial = $true,
    [boolean]$symbols = $false
)

# Use TLS 1.2 and 1.1, otherwise a few downloads will fail
[Net.ServicePointManager]::SecurityProtocol = "Tls12, Tls11"

Write-Host "      ___  _               _   _" -ForegroundColor Green
Write-Host "     |   \(_)______ ___ __| |_(_)_ _  ___" -ForegroundColor Green
Write-Host "     | |) | (_-<_-</ -_) _|  _| | ' \/ _ |" -ForegroundColor Green
Write-Host "     |___/|_/__/__/\___\__|\__|_|_||_\__,|   /\/|" -ForegroundColor Green
Write-Host "     |  \/  |__ _| |_ __ ____ _   _ _|___/  |/\/" -ForegroundColor Green
Write-Host "     | |\/| / _  | \ V  V / _  |_| '_/ -_)" -ForegroundColor Green   
Write-Host "     |_|  |_\__,_|_|\_/\_/\__,_(_)_| \___| `n`n" -ForegroundColor Green
Write-Host "           Malware Analysis VM Setup"      
Write-Host " Marius 'f0wL' Genheimer | https://dissectingmalwa.re `n"

# Post-install: Pre-Load debugging symbols
if ($symbols){
    Write-Host "`nThis might take a moment, please be patient! 'mismatched or not found errors' can be ignored`n" -ForegroundColor Yellow
    cmd.exe /c '"C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\symchk.exe" /r C:\Windows\System32\ /s srv*c:\symbols*http://msdl.microsoft.com/download/symbols'
    Pause
    Exit
}

function New-Menu {
    # Powershell Menu https://adamtheautomator.com/build-powershell-menu/
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$Title,

        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$Question,

        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [ChoiceDescription[]]$Options
    )

    Write-Output $result = $host.ui.PromptForChoice($Title, $Question, $Options, 0)

}

function Set-RegKey {
    # https://devblogs.microsoft.com/scripting/update-or-add-registry-key-value-with-powershell/
    param (
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$Path,

        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$Name,

        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$Value
    )

    if(!(Test-Path $Path)){
        New-Item -Path $Path -Force | Out-Null
        New-ItemProperty -Path $Path -Name $Name -Value $Value ` -PropertyType DWORD -Force | Out-Null
    }
    else {
        New-ItemProperty -Path $Path -Name $Name -Value $Value ` -PropertyType DWORD -Force | Out-Null
    }
    
}

function Download-File {
    param (
        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$uri,

        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$filepath
    )

    try{
        $CurrentProgressPref = $ProgressPreference
        $ProgressPreference = "SilentlyContinue"
        Invoke-WebRequest -Uri $uri -OutFile $filepath
        $ProgressPreference = $CurrentProgressPref
    } catch {
        Write-Error -Message "Unable to download file from $uri. Error was: $_" -ErrorAction Continue
    }
    Write-Host "[OK]" -ForegroundColor Green
}

# First menu: Select between Static/Dynamic Analysis
$static = New-Object System.Management.Automation.Host.ChoiceDescription '&Static', 'VM Flavor: Static Analysis'
$dynamic = New-Object System.Management.Automation.Host.ChoiceDescription '&Dynamic', 'VM Flavor: Dynamic Analysis'
$vm_options = [System.Management.Automation.Host.ChoiceDescription[]]($static, $dynamic)
$vm_result = New-Menu -Title '================ VM Type =================' -Question 'Which type of VM would you like to set up?' -Options $vm_options

switch ($vm_result)
{
    0 {$tools = Get-Content -Path '.\static-tools.json'}
    1 {$tools = Get-Content -Path '.\dynamic-tools.json'}
}

# Get number of lines from the tool list
$length = $tools.count
# Parse JSON
$toolsObj = $tools | ConvertFrom-Json

# Create a subdirectory called "downloads" to store the files in
$downloadsFolder = $PSScriptRoot+"\"+"downloads" 

# Create subfolder "downloads" in the current directory
if (-not (Test-Path -LiteralPath $downloadsFolder)) {
    try {
        New-Item -Path $downloadsFolder -ItemType Directory -ErrorAction Stop | Out-Null
    }
    catch {
        Write-Error -Message "Unable to create directory '$downloadsFolder'. Error was: $_" -ErrorAction Stop
    }
}

# loop through the tool list
For ($i=0; $i -lt $length; $i++) {
    # some tools require manual downloading
    if (-not $toolsObj[$i].manual){
        Write-Host "`nDownloading" $toolsObj[$i].name"..."
        # extract filename from URL
        $filename = $toolsObj[$i].url.Substring($toolsObj[$i].url.LastIndexOf("/") + 1)
        # append filename to folder path
        $filepath = $downloadsFolder+"\"+$filename
        # check for passed arguments;
        # if the user selected professional use...
        if (-not $nonCommercial){
            # ...and the current tool doesn't allow it
            if (-not $toolsObj[$i].nonCommercial){
                Write-Host "[SKIP, nonCommercial]" -ForegroundColor Yellow
            } else {
                Download-File -uri $toolsObj[$i].url -filepath $filepath 
            }
        } else {
            # default: download all tools :)
            Download-File -uri $toolsObj[$i].url -filepath $filepath
        }
    }
}

Write-Host "`nLet's download some Tools from Microsoft:"
$msoft = Get-Content -Path '.\microsoft-tools.json'
# Get number of lines from the tool list
$msoft_len = $msoft.count
# Parse JSON
$msoftObj = $msoft | ConvertFrom-Json

# Microsoft uses weird short-links etc. so we'll open these pages in a webbrowser
For ($j=0; $j -lt $msoft_len; $j++) {
    Write-Host "Opening in Browser: "$msoftObj[$j].name"..."
    Start-Process $msoftObj[$j].url
    Start-Sleep -s 5
}

$osVer = [System.Environment]::OSVersion.Version.Major
if ($osVer -eq 6){
    # Python dropped support for Windows 7 SP1 with 3.9, so we will stick with 3.8
    Write-Host "Detected Windows 7, downloading Python 3.8 ..."
    For ($i=0; $i -lt $length; $i++) { 
        if ($toolsObj[$i].name -eq "Python3 Legacy"){
            $filename = $toolsObj[$i].url.Substring($toolsObj[$i].url.LastIndexOf("/") + 1)
            $filepath = $downloadsFolder+"\"+$filename
            Download-File -uri $toolsObj[$i].url -filepath $filepath
        }
    }
} else {
    For ($i=0; $i -lt $length; $i++) { 
    Write-Host "Downloading Python 3.9 ..."
        if ($toolsObj[$i].name -eq "Python3"){
            $filename = $toolsObj[$i].url.Substring($toolsObj[$i].url.LastIndexOf("/") + 1)
            $filepath = $downloadsFolder+"\"+$filename
            Download-File -uri $toolsObj[$i].url -filepath $filepath 
        }
    }
}

switch ($vm_result)
{
    0 {Write-Host "`nDon't forget to manually download Binary Ninja, VBDecompiler Pro, Cerbero Suite etc.`n" -ForegroundColor Yellow}
    1 {
        # open in Browser since it is not possible to directly link to a file -.-
        For ($i=0; $i -lt $length; $i++) { 
            if ($toolsObj[$i].manual){
            if ($toolsObj[$i].name -eq "NetworkMiner"){
                Start-Process $toolsObj[$i].url
                Start-Sleep -s 5
            }
            if ($toolsObj[$i].name -eq "OllySubScript"){
                Start-Process $toolsObj[$i].url
                Start-Sleep -s 5
            }
             if ($toolsObj[$i].name -eq "CheatEngine"){
                Start-Process $toolsObj[$i].url
                Start-Sleep -s 5
            }
        }
        }

        # menu dialog for ASLR 
        $aslr_yes = New-Object System.Management.Automation.Host.ChoiceDescription '&Yes', 'Disable Address Space Layout Randomization on the system'
        $aslr_no = New-Object System.Management.Automation.Host.ChoiceDescription '&No', 'Leave it as it is, I like ASLR'
        $aslr_options = [System.Management.Automation.Host.ChoiceDescription[]]($aslr_yes, $aslr_no)
        $aslr_result = New-Menu -Title '================== ASLR ==================' -Question 'Would you like to disable Address Space Layout Randomization on this system?' -Options $aslr_options

        switch ($aslr_result)
        {
            0 {
                # set the registry value to disable ASLR for the debugging VM
                Set-RegKey -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management' -Name 'MoveImages' -Value '0'
                Write-Host "Please remember to reboot the VM once you are done here!`n" -ForegroundColor Yellow
            }
            1 {
                Write-Host "`nGot it, not messing around with the Registry :D`n"
            }
        }

        # menu dialog for Hypervisor Scripts 
        $hv_vmware = New-Object System.Management.Automation.Host.ChoiceDescription '&VMware', 'Download d4rksystem/VMwareCloak from Github'
        $hv_vbox = New-Object System.Management.Automation.Host.ChoiceDescription '&VirtualBox', 'Download d4rksystem/VBoxCloak from Github'
        $hv_no = New-Object System.Management.Automation.Host.ChoiceDescription '&No', 'Do not download hypervisor hiding scripts'
        $hv_options = [System.Management.Automation.Host.ChoiceDescription[]]($hv_vmware, $hv_vbox, $hv_no)
        $hv_result = New-Menu -Title '============ Hypervisor Hiding ============' -Question 'Would you like to download a hypervisor-hiding script?' -Options $hv_options

        switch ($hv_result)
        {
            0 {
               # loop through the tool list again
                For ($i=0; $i -lt $length; $i++) { 
                    if ($toolsObj[$i].name -eq "VMwareCloak"){
                        $filename = $toolsObj[$i].url.Substring($toolsObj[$i].url.LastIndexOf("/") + 1)
                        $filepath = $downloadsFolder+"\"+$filename
                        Download-File -uri $toolsObj[$i].url -filepath $filepath
                    }
                }
            }
            1 {
                For ($i=0; $i -lt $length; $i++) { 
                    if ($toolsObj[$i].name -eq "VBoxCloak"){
                        $filename = $toolsObj[$i].url.Substring($toolsObj[$i].url.LastIndexOf("/") + 1)
                        $filepath = $downloadsFolder+"\"+$filename
                        Download-File -uri $toolsObj[$i].url -filepath $filepath 
                    }
                }
            }
            2 {
                Write-Host "`nOK, continuing.`n"
            }
        }

    }
}

Write-Host "`nEnabling well-known extensions and hidden files/folders in Explorer"
# Hidden files, folders or drives
Set-RegKey -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced' -Name 'Hidden' -Value '1'
# Show well-known file extensions
Set-RegKey -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced' -Name 'HideFileExt' -Value '0'
# Show protected operating system files
Set-RegKey -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced' -Name 'ShowSuperHidden' -Value '1'
# Restart Windows Explorer
Stop-Process -processname explorer

Write-Host "`nThat's it! Happy reversing :)`n" -ForegroundColor Green
